package com.ia.aistream.manager.dxfcomponent.util;

import com.ia.aistream.model.dxfcomponent.entity.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/****
 * 实现图纸的扩展功能
 * @author XiaoYu
 */

public class DrawExtensionUtil {

    /***
     * 获取图纸中的索引信息
     * @param dxfPath
     * @param newPath
     * @return
     */
    public static DxfDraw getDxfDraw(String dxfPath, String newPath){

        List<String> filterData = filterLayer(dxfPath);
        Map<String, Object> map = deleteSurplusData(filterData);
        List<String> list = (List<String>) map.get("resultData");
        double[] size = (double[]) map.get("size");
        List<String> result = new ArrayList<>();
        for (String s:list){
            result.add(s + "\n");
        }
        writeNIO(result, newPath);
        // 获取原始数据
        List<FileComponent> equipment = getFileComponent(list);
        return getDrawIndex(equipment, size[1], size[0]);
    }

    /***
     * 获取图纸大小和索引信息
     * @param dxfPath
     * @param newPath
     * @return
     */
    public synchronized static Map<String, Object> getDxfDrawSize(String dxfPath, String newPath){

        // 获取过滤掉图层后的数据
        List<String> filterData = filterLayer(dxfPath);
        if(filterData==null){
            return null;
        }
        // 获取删除图框以外的数据
        Map<String, Object> map = deleteSurplusData(filterData);
        List<String> list = (List<String>) map.get("resultData");
        double[] size = (double[]) map.get("size");
        List<String> result = new ArrayList<>();
        for (String s:list){
//            s = s.replaceAll("\\\\C\\d{1};","");
            result.add(s + "\n");
        }
        writeNIO(result, newPath);
        // 获取原始数据
        List<FileComponent> equipment = getFileComponent(list);
        if(size!=null){
            map.put("dxfDraw", getDrawIndex(equipment, size[1], size[0]));
        }else {
            map.put("dxfDraw", getDrawIndex(equipment, 0.0, 0.0));
        }

        return map;
    }

    /***
     * 获取图纸的设备信息
     * @param dxfPath
     * @return
     */
    public static List<DxfComponent> getDxfComponent(String dxfPath, double[] size){

        // 读取dxf文件中的数据
        List<String> list = FileUtilTest.readDxfDataSource(dxfPath);
        List<FileComponent> equipment = getFileComponent(list);
        List<DxfComponent> dxfComponentList = getEquipment(equipment, size);
        // 对设备进行排序
        return sortEquipment(dxfComponentList);
    }

    /***
     * 对设备进行排序
     * @param list
     * @return
     */
    public static List<DxfComponent> sortEquipment(List<DxfComponent> list){

        Comparator com = new Comparator() {
            // 重写
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof DxfComponent && o2 instanceof DxfComponent) {// 判断是否为Employee类型
                    DxfComponent d1 = (DxfComponent) o1;
                    DxfComponent d2 = (DxfComponent) o2;
                    String contentC1 = d1.getContentC();
                    String contentC2 = d2.getContentC();
                    String zM1 = "";
                    String sZ1 = "";
                    String zM2 = "";
                    String sZ2 = "";
                    // 如果是三位数字
                    if(getNumLen(contentC1)){
                        zM1 = contentC1.substring(3);
                        sZ1 = contentC1.substring(0, 3);
                    }else {
                        zM1 = contentC1.substring(4);
                        sZ1 = contentC1.substring(0, 4);
                    }

                    if(getNumLen(contentC2)){
                        zM2 = contentC2.substring(3);
                        sZ2 = contentC2.substring(0, 3);
                    }else {
                        zM2 = contentC2.substring(4);
                        sZ2 = contentC2.substring(0, 4);
                    }
                    int i = zM1.compareTo(zM2);
                    // 如果两个相等，则比较数字
                    if(i==0){
                        // 比较数字
                        int num = sZ1.compareTo(sZ2);
                        return num!=0 ? num : -1;
                    }else{
                        return zM1.compareTo(zM2);
                    }
                }
                return 0;
            }
        };

        TreeSet<DxfComponent> tree = new TreeSet<>(com);
        for (DxfComponent dxf: list){
            tree.add(dxf);
        }

        List<DxfComponent> result = new ArrayList<>(tree);
        return result;
    }

    /***
     * 获取dxf文件中的所有隐藏图层
     * @param stringList
     * @return  表示隐藏图层
     */
    public static List<String> getSurplusLayer(List<String> stringList){
        // 存放隐藏图层
        List<String> list = new ArrayList<>();

        boolean flag = false;
        String layerName = "";
        // 遍历所有数据，获取图层信息
        for(int i=0; i<stringList.size();i++){
            if("100".equals(stringList.get(i)) && "AcDbLayerTableRecord".equals(stringList.get(i+1))){
                flag = true;
            }else if(flag && "  2".equals(stringList.get(i))){
                layerName = stringList.get(i+1);
            }else if(flag && " 62".equals(stringList.get(i))){
                // 判断该值是否为负值
                if(stringList.get(i+1).contains("-")){
                    list.add(layerName);
                }
            }

            // 判断循环结束
            if(list.size()>0 && "  0".equals(stringList.get(i)) && "ENDTAB".equals(stringList.get(i+1))){
                break;
            }
        }

        return list;
    }

    /***
     * 删除掉隐藏图层的数据，返回删除隐藏图层后的结果
     * @param dxfPath
     * @return
     */
    public synchronized static List<String> filterLayer(String dxfPath){
        // 存放删除隐藏图层的数据
        List<String> list = new ArrayList<>();

        // 获取dxf文件中的原始数据
        List<String> stringList = FileUtilTest.readDxfDataSource(dxfPath);

        if(stringList==null){
            return null;
        }

        // 获取隐藏的图层名称
        List<String> layer = getSurplusLayer(stringList);

        // 如果没有隐藏图层则不需要删除
        if(layer.size() > 0){

            boolean startFlag = false;
            boolean flag = false;

            // 定义删除的flag
            boolean delFlag = false;

            List<String> record = new ArrayList<>();
            // 遍历所有的数据
            for(int i=0; i<stringList.size(); i++){
                // 将数据写入需要的集合
                String s = stringList.get(i);

                if("ENTITIES".equals(s)){
                    startFlag = true;
                }
                // 开始计数
                if(startFlag){

                    // 去掉多余的字符
                   // s = s.replaceAll("\\\\C\\d{1};","");
                    if ("  0".equals(s)) {
                        if(!delFlag && record.size()>0){
                            list.addAll(record);
                        }
                        record.clear();
                        flag = true;
                        delFlag = false;
                    }else if(flag && "  8".equals(s) && layer.contains(stringList.get(i+1))){
                        delFlag = true;
                    }else if(flag && "SECTION".equals(s) && "  2".equals(stringList.get(i+1)) && "OBJECTS".equals(stringList.get(i+2))){
                        list.add(stringList.get(i-1));
                        list.add(s);
                        startFlag  = false;
                    }

                    // 记录中间的字符串
                    record.add(s);
                }else{
                    list.add(s);
                }
            }
        }else{
            list.addAll(stringList);
        }
        // 将结果写入文件
        return list;
    }

    /***
     * 删除图框外的数据,返回删除后的结果
     * 返回图框比例
     * @param filterData
     * @return
     */
    public static Map<String,Object> deleteSurplusData(List<String> filterData){

        Map<String,Object> map = new HashMap<>();
//        List<String> filterData = FileUtilTest.readDxfDataSource(dxfPath);
        // 获取最后结果
        List<String> result = new ArrayList<>();

        // 获取坐标
        double[] size = FileUtilTest.drawSize(filterData);
        // 如果数据为空，则返回原始数据
        if(size==null){
            map.put("resultData", filterData);
            map.put("size", null);
            return map;
        }
        double leftX = size[0];
        double leftY = size[1];
        double rightX = size[2];
        double rightY = size[3];
//        double leftX = size[0];
//        double leftY = size[3];
//        double rightX = size[4];
//        double rightY = size[5];
        double width = Math.abs(rightX - leftX);
        double height = Math.abs(leftY - rightY);
        if(width < height){
            width = height;
        }

        // 定义开始控制变量
        boolean startFlag = false;
        boolean delFlag = false;
        boolean flag = false;
        boolean sizeFlag = false;
//        StringBuilder entity = new StringBuilder();

        List<String> record = new ArrayList<>();
        // 遍历原始数据，删除多余数据
        for(int i=0; i<filterData.size(); i++){
            String s = filterData.get(i);
            // 确定开始循环的位置
            if("ENTITIES".equals(s)){
                startFlag = true;
            }

            if(startFlag){
                if("  0".equals(s)){
                    sizeFlag = false;
                    if(!delFlag && record.size()>0){
                        result.addAll(record);
                    }
                    if(handleType(filterData.get(i+1))){
                        sizeFlag = true;
                    }
                    record.clear();
                    flag = true;
                    delFlag = false;
                }else if(flag && " 10".equals(s)){
                    double x = Double.parseDouble(filterData.get(i + 1));
                    if(!"0.0".equals(filterData.get(i+1))) {
                        if (x < leftX || x > rightX) {
                            delFlag = true;
                        }
                    }

                }else if(flag && " 20".equals(s)){
                    double y = Double.parseDouble(filterData.get(i + 1));
                    if(!"0.0".equals(filterData.get(i+1))) {
                        if (y > leftY || y < rightY) {
                            delFlag = true;
                        }
                    }
                }else if(sizeFlag && " 40".equals(s)){
                    double y = Double.parseDouble(filterData.get(i + 1));
                    if(!"0.0".equals(filterData.get(i+1))) {
                        if (y < (1.0/1000*width)) {
                            delFlag = true;
                        }
                    }
                }else if("SECTION".equals(s) && "  2".equals(filterData.get(i+1)) && "OBJECTS".equals(filterData.get(i+2))){
                    result.add(filterData.get(i-1));
                    result.add(s);
                    startFlag  = false;
                }else if("Embedded Object".equals(s)){
                    flag  = false;
                }
                // 记录中间的字符串
                record.add(s);
            }else{
                result.add(s);
            }

        }

        // 过滤多余的Block段
        List<String> list = deleteBlocksData(result, size);
        double[] drawSize = new double[4];
        // 图纸的实际长度和宽度
        drawSize[0] = Math.abs(rightX-leftX);
        drawSize[1] = Math.abs(leftY-rightY);
        // 转化的图纸比例大小
//        drawSize[2] = size[0];
//        drawSize[3] = size[1];

        map.put("resultData", list);
        map.put("size", drawSize);
        return map;
    }

    /***
     * 获取超过边界的BLOCK段
     * @param filterData
     * @param size
     * @return
     */
    public static List<String> deleteBlocksData(List<String> filterData, double[] size){

        List<String> delBlocks = new ArrayList<>();
        List<String> result = new ArrayList<>();
        // 图幅的大小
        double leftX = size[0];
        double leftY = size[1];
        double rightX = size[2];
        double rightY = size[3];
//        double leftX = size[2];
//        double leftY = size[3];
//        double rightX = size[4];
//        double rightY = size[5];

        System.out.println("leftX=" + leftX);
        System.out.println("leftY=" + leftY);
        System.out.println("rightX=" + rightX);
        System.out.println("rightY=" + rightY);
        // 定义开始控制变量
        boolean startFlag = false;
        boolean delFlag = false;
        boolean flag = false;

        String name = "";
        // 遍历原始数据，删除多余数据
        for(int i=0; i<filterData.size(); i++){
            String s = filterData.get(i);
            // 确定开始循环的位置
            if("ENTITIES".equals(s)){
                startFlag = true;
            }

            if(startFlag){
                if("100".equals(s) && "AcDbBlockReference".equals(filterData.get(i+1))){
                    flag = true;
                }else if(flag && "  2".equals(s)){
                    name = filterData.get(i+1);
                }else if(flag && " 10".equals(s)){
                    double x = Double.parseDouble(filterData.get(i + 1));
                    if (x < leftX || x > rightX) {
                        delFlag = true;
                    }
                }else if(flag && " 20".equals(s)){
                    double y = Double.parseDouble(filterData.get(i + 1));
                    if (y > leftY || y < rightY) {
                        delFlag = true;
                    }

                    // 判断是否需要删除的block
                    if(delFlag){
                        delBlocks.add(name);
                    }
                    flag = false;
                    delFlag = false;
                }else if("SECTION".equals(s) && "  2".equals(filterData.get(i+1)) && "OBJECTS".equals(filterData.get(i+2))){
                    startFlag  = false;
                }else if("Embedded Object".equals(s)){
                    flag  = false;
                }
            }
        }

        if(delBlocks.size()>1){
            boolean removeFlag = false;
            delFlag = false;
            flag = false;
            startFlag = false;
            // 循环删除BLOCKS段的数据
            for(int i=0; i<filterData.size(); i++) {
                String s = filterData.get(i);
                // 确定开始循环的位置
                if ("BLOCKS".equals(s)) {
                    startFlag = true;
                }
                if(startFlag){
                    if("  0".equals(s) && "BLOCK".equals(filterData.get(i+1))){
                        flag = true;
                    }else if(flag && "  2".equals(s) && delBlocks.contains(filterData.get(i+1))){
                        delFlag = true;
                    }else if(delFlag && "  1".equals(s) && "".equals(filterData.get(i+1))){
                        result.add(s);
                        result.add(filterData.get(i+1));
                        // 获取删除数据
                        removeFlag = true;
                        flag = false;
                        delFlag = false;
                    }else if("  0".equals(s) && "ENDBLK".equals(filterData.get(i+1))){
                        // 停止删除
                        removeFlag = false;
                    }else if("SECTION".equals(s) && "  2".equals(filterData.get(i+1)) && "ENTITIES".equals(filterData.get(i+2))){
                        startFlag  = false;
                    }
                    if(!removeFlag){
                        result.add(s);
                    }
                }else{
                    result.add(s);
                }

            }
            return result;
        }

        return filterData;
    }

    /****
     * 获取数据类型为TEXT和MTEXT类型的数据
     * @param resultData
     * @return
     */
    public static List<FileComponent> getFileComponent(List<String> resultData){

        List<FileComponent> fcList = new ArrayList<>();

        // 声明对象
        FileComponent fc = null;

        // 定义开始的变量
        boolean startFlag = false;
        boolean flag = false;
        //  处理后的数据
        for(int i=0; i<resultData.size(); i++){
            String s = resultData.get(i);
            // 确定开始读取数据的位置
            if("ENTITIES".equals(s)){
                startFlag = true;
            }

            if(startFlag){
                if("  0".equals(s)){
                    if(fc!=null && fc.getOriginal()!=null && !fcList.contains(fc) && fc.getOriginal().length()>1){
                        fcList.add(fc);
                    }
                    flag = false;
                }

                if("  0".equals(s) && handleType(resultData.get(i+1))){
                    fc = new FileComponent();
                    flag = true;
                }else if (flag && "  8".equals(s)){
                    fc.setLayer(resultData.get(i+1));
                }else if (flag && " 10".equals(s)){
                    fc.setX(Double.parseDouble(resultData.get(i+1)));
                }else if (flag && " 20".equals(s)){
                    fc.setY(Double.parseDouble(resultData.get(i+1)));
                }else if (flag && "  1".equals(s)){
                    fc.setOriginal(resultData.get(i+1));
                }else if(flag && "  7".equals(s)){
                    fc.setStyle(resultData.get(i+1));
                }else if("Embedded Object".equals(s)){
                    flag = false;
                }
            }

            if ("OBJECTS".equals(s)){
                startFlag = false;
            }
        }
        return fcList;
    }
    /*************************************************/
    /***
     * 获取文件中的索引信息（标题栏）
     * @param list
     * @return
     */
    private static DxfDraw getDrawIndex(List<FileComponent> list, double height, double width){

        //判断集合是否为空，为空则返回null值
        if(list==null || list.size()==0){
            return new DxfDraw();
        }

        //创建索引信息的对象
        DxfDraw titleBar = new DxfDraw();

        //遍历原始数据
        for (FileComponent fc : list){
            //获取原始数据
            String content = fc.getOriginal();
            //如果字符串长度小于2位则直接跳过本次循环
            if(content.length()<2){
                continue;
            }
            //处理原始数据，获取需要的值
            String tb = handleOriginal(content);

            if(tb.startsWith("FQ") && tb.length()>10){
                titleBar.setFileCode(tb);
            }
// FQ0-SED-DWOPLC-0000+核岛除盐水分配系统1、2号机组流程图+003  不满足条件

            //处理标题栏数据
            if("设备标注文字".equals(fc.getStyle())){

                //对数据进行规则验证，判断是否是图纸编号
                if(tb.startsWith("FQ") && tb.length()>10){

                    titleBar.setFileCode(tb);
                }else if(handleSystem(tb)){
                    //判断是否是系统值
                    titleBar.setSystem(tb);
                }else if(handleFileName(tb)){
                    //判断是否是文件名称
                    titleBar.setFileName(tb);
                }else if(handleVersion(tb)) {
                    //验证是否是版本
                    titleBar.setVersion(tb);
                }else if(handleEdition(tb)){
                    //验证是否是版次
                    titleBar.setEdition(tb);
                }else if(handleSubItem(tb)){
                    //验证是否是子项值
                    titleBar.setSubitem(tb);
                }
            }
        }

        // 验证对象中是否含有该属性，如果没有则进行利用坐标进行获取
        // 判断是否有无文件名称信息
        if(titleBar.getFileName()==null){
            String fileName = getFileName(list);
            titleBar.setFileName(fileName);
        }

        if(height>1){
            System.out.println("成功height=" + height);
            // 判断是否有版次信息
//        if(titleBar.getEdition()==null){
            String edition = getEdition(list, height, width);
            titleBar.setEdition(edition);
//        }
            // 判断是否含有版本信息
            if(titleBar.getVersion()==null){
                String version = getVersion(list, height, width);
                titleBar.setVersion(version);
            }

            // 判断是否含有系统信息
            if(titleBar.getSystem()==null){
                String system = getSystem(list, height, width);
                titleBar.setSystem(system);
            }

            // 判断是否含有子项信息
            String subItem = getSubItem(list, height, width);
            titleBar.setSubitem(subItem);
        }else{

            System.out.println("失败height=" + height);
            titleBar.setStatus(1);
        }

        return titleBar;
    }

    /***
     * 获取设备信息
     * @param fcList
     * @return
     */
    public static List<DxfComponent> getEquipment(List<FileComponent> fcList, double[] size){
        List<DxfComponent> dxfComponentList = new ArrayList<>();

        // 存储需要进行拼接的设备信息
        List<FileComponent> numList = new ArrayList<>();
        List<FileComponent> charList = new ArrayList<>();
        List<FileComponent> equipList = new ArrayList<>();

        for(int i=0; i<fcList.size(); i++){

            FileComponent fc = fcList.get(i);
            // 获取原数据
            String original = fc.getOriginal();
            String str = handleOriginal(original);

            if(str.length()<2){
                continue;
            }

            // 验证是否是设备编码，如果是则存储到设备对象中
            if (handleEquipmentCode(str)){
                DxfComponent dxfComponent = new DxfComponent();

                dxfComponent.setContentC(str);
                //存储部件的类型
                dxfComponent.setType("E");
                //保存原始数据
                dxfComponent.setContentO(original);
                //保存图层数据
                dxfComponent.setLayer(fc.getLayer());
                //获取每个点对应的坐标
                dxfComponent.setPositionX(fc.getX());
                dxfComponent.setPositionY(fc.getY());

                dxfComponentList.add(dxfComponent);
            }else {
                // 如果是数字则放入数字的集合中，是字母就放入字母的集合中
                if (handleNumber(str)) {
                    numList.add(fc);
                }else if(handleLetter(str)){
                    charList.add(fc);
                }else if(isEquipment(str)){
                    equipList.add(fc);
                }
            }

        }
        // 进行设备的拼接计算
        if(size!=null){
            List<DxfComponent> list = handleDxfComponent(numList, charList, size);
            dxfComponentList.addAll(list);
        }

        List<DxfComponent> componentList = getEquipment9(equipList);
        dxfComponentList.addAll(componentList);
        return dxfComponentList;
    }

    /***
     * 处理9位设备编码
     * @param list
     * @return
     */
    private static List<DxfComponent> getEquipment9(List<FileComponent> list){
        List<DxfComponent> dxfComponentList = new ArrayList<>();

        for (FileComponent fc:list){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            String result = subEquipment(s);
            if(result!=null){
                if(result.contains("-")){
                    String[] split = result.split("-");
                    for(String str:split){
                        DxfComponent dx = new DxfComponent();
                        dx.setContentO(original);
                        dx.setType("E");
                        dx.setPositionY(fc.getY());
                        dx.setPositionX(fc.getX());
                        dx.setLayer(fc.getLayer());
                        dx.setContentC(str);
                        dxfComponentList.add(dx);
                    }
                }else {
                    DxfComponent dx = new DxfComponent();
                    dx.setContentO(original);
                    dx.setType("E");
                    dx.setPositionY(fc.getY());
                    dx.setPositionX(fc.getX());
                    dx.setLayer(fc.getLayer());
                    dx.setContentC(result);
                    dxfComponentList.add(dx);
                }
            }
        }
        return dxfComponentList;
    }

    /**********************************************************************************
     * 进行设备拼接的算法处理
     * @param
     * @return
     */
    private static List<DxfComponent> handleDxfComponent(List<FileComponent> numList, List<FileComponent> charList, double[] size){

        List<DxfComponent> list = new ArrayList<>();
        double width = size[0];
        double height = size[1];
        double xA = 3/1000.0 * width;
        double yA = 12.5/1000.0 * height;
        double yB = 2/1000.0 * height;
        double xB = 5/1000.0 * width;
        double yC = 7.5/10000.0 * height;
        double xC = 18/1000.0 * width;
        double xD = 6/10000.0 * width;
        double yD = 15/1000.0 * height;

        for (FileComponent numFC: numList){
            for(FileComponent charFC : charList){

                // C: 识别：y绝对相同，x差2点
                if(Math.abs(numFC.getY()-charFC.getY())< yC){
                    if(Math.abs(charFC.getX() - numFC.getX()) < xC){

                        DxfComponent dxfComponent = handleEquipment(numFC, charFC);
                        if(dxfComponent!=null){
                            list.add(dxfComponent);
                            charList.remove(charFC);
                            break;
                        }

                    }
                }

                // D: 识别X绝对值相同，y差两点
                if(Math.abs(charFC.getX() - numFC.getX())< xD){
                    if(Math.abs(numFC.getY()-charFC.getY()) < yD){

                        DxfComponent dxfComponent = handleEquipment(numFC, charFC);
                        if(dxfComponent!=null){
                            list.add(dxfComponent);
                            charList.remove(charFC);
                            break;
                        }
                    }
                }

                // A: 识别x相同，Y差一点
                if (Math.abs(charFC.getX() - numFC.getX())< xA){
                    if(Math.abs(numFC.getY()-charFC.getY())< yA){

                        DxfComponent dxfComponent = handleEquipment(numFC, charFC);
                        if(dxfComponent!=null){
                            list.add(dxfComponent);
                            charList.remove(charFC);
                            break;
                        }
                    }
                }

                // B: 识别y相同，X差一点
                if(Math.abs(numFC.getY()-charFC.getY())< yB) {
                    if (Math.abs(charFC.getX() - numFC.getX()) < xB) {

                        DxfComponent dxfComponent = handleEquipment(numFC, charFC);
                        if(dxfComponent!=null){
                            list.add(dxfComponent);
                            charList.remove(charFC);
                            break;
                        }
                    }
                }
            }
        }
        return list;
    }

    /***
     * 将符合设备编码格式的两个对象，拼接为一个对象
     * @param numFC
     * @param charFC
     * @return
     */
    private static DxfComponent handleEquipment(FileComponent numFC, FileComponent charFC){
        // 获取原始数据
        String numStr = numFC.getOriginal();
        String charStr = charFC.getOriginal();
        // 获取处理后的数据
        String numHandle = handleOriginal(numStr);
        String charHandle = handleOriginal(charStr);
        String result = numHandle + charHandle;

        // 处理设备编码
        if (handleEquipmentCode(result)){
            DxfComponent dxfComponent = new DxfComponent();
            dxfComponent.setContentC(result);
            dxfComponent.setLayer(numFC.getLayer());
            dxfComponent.setPositionX(numFC.getX());
            dxfComponent.setPositionY(numFC.getY());
            dxfComponent.setType("E");
            dxfComponent.setContentO(numStr+"-"+charStr);

            return dxfComponent;
        }

        return null;
    }


    /***
     * 处理原始数据
     * @param origin
     * @return
     */
    public static String handleOriginal(String origin){

        // 替换格式中的特殊字符
        origin = origin.replace("\\C256", "");
        origin = origin.replaceAll(" ", "");
        origin = origin.replaceAll("\\\\C\\d{1};","");
        origin = origin.replaceAll("\\\\W\\d{1}\\.\\d{1};", "");
        origin = origin.replaceAll("\\\\W\\d{1};", "");
        origin = origin.replace("\\A1", "");
        //origin = origin.replace("\\T0.9", "");
        origin = origin.replaceAll("\\\\T\\d{1}\\.\\d+", "");
//        origin = origin.replace("\\H0.924x", "");
//        origin = origin.replace("\\H0.8772x", "");
//        origin = origin.replace("\\H0.9997x", "");
//        origin = origin.replace("\\H1.2319x", "");
//        origin = origin.replace("\\H1.3859x", "");
//        origin = origin.replace("\\H1.5399x", "");
//        origin = origin.replace("\\H0.6667x", "");
//        origin = origin.replace("\\H0.75004x", "");
//        origin = origin.replace("\\H1.082x", "");
//        origin =origin.replace("\\H1.2167x", "");
        origin =origin.replaceAll("\\\\H\\d{1}\\.\\d+x", "");
        origin =origin.replace("\\H1x", "");
        origin = origin.replace("\\pxql", "");
        origin = origin.replace("\\pxqc", "");
        origin = origin.replace("\\pxse0.55556", "");
        origin = origin.replace("\\pxr1.6649", "");
        origin = origin.replace("\\pxi-2,l3,t3;","");
        origin = origin.replaceAll("\\\\pi-\\d{1}\\.\\d+;", "");
        //origin = origin.replace("\\pi-4.133", "");
        origin = origin.replaceAll("\\\\pxsm\\d{1}\\.\\d{1},qc", "");
        origin = origin.replaceAll("\\\\T\\d{1};", "");
        origin = origin.replaceAll("\\\\fTimes New Roman\\|b\\d{1}\\|i0\\|c\\d*\\|p18", "");
        origin = origin.replaceAll( "\\\\f@SimSun\\|b\\d{1}\\|i0\\|c\\d*\\|p2", "");
        origin = origin.replaceAll("\\\\f[a-zA-Z]*\\s*[a-zA-Z]*\\|b\\d{1}\\|i0\\|c\\d*\\|p\\d{1,2}", "");
        origin = origin.replaceAll("\\\\f[a-zA-Z0-9_]+\\|b\\d{1}\\|i0\\|c\\d*\\|p\\d{1,2}", "");
        origin = origin.replaceAll("\\\\f[\\u4e00-\\u9fa5]+\\|b\\d{1}\\|i0\\|c\\d*\\|p\\d{1,2};", "");
        origin = origin.replaceAll("\\\\Fromand.shx\\|c\\d+;", "");
        origin = origin.replaceAll("\\\\F[a-zA-Z]+\\.[a-zA-Z]+,[a-zA-Z]+\\.[a-zA-Z]+;", "");
        origin = origin.replaceAll("\\\\F[a-zA-Z]+,[a-zA-Z]+\\|c\\d+;", "");
        origin = origin.replace("\\pxr0.48365,t1,2", "");
        origin = origin.replaceAll("\\\\F[a-zA-Z]+\\.[a-zA-Z0-9_]+;", "");
        origin = origin.replaceAll("\\\\pxse\\d*\\.\\d+;", "");
        origin = origin.replace("|", "");
        origin = origin.replace(";", "");

        origin = origin.replace("{", "");
        origin = origin.replace("}", "");
        //将提取数据中的\\P去掉，并去掉所有" "
        origin = origin.replace("\\P","");
        return origin;
    }

    /***
     * 将过滤后的数据写入到本地dxf文件
     * @param list
     * @param newFilePath
     */
    public static void writeNIO(List<String> list, String newFilePath) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(newFilePath);
            FileChannel channel = fos.getChannel();
            byte[] by = null;
            String[] strings = list.toArray(new String[list.size()]);
            for(String s:strings){//utf-8
                ByteBuffer src = Charset.forName("utf-8").encode(s);

                channel.write(src);
            }

        } catch (Exception ee) {
            ee.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }


    /************************ 私有化方法吗，正则表达式工具类 ********************************/

    /***
     * 验证字符串是否是设备编码
     * @param msg
     * @return
     */
    private static Boolean handleEquipmentCode(String msg){

        //设置正则表达式:以三位数字或四位开头以两位字母结尾或者以三位数字结尾
        String equPattern = "^\\d{3,4}[a-zA-Z]{2,3}\\d?$";
        Pattern equR = Pattern.compile(equPattern);
        Matcher equM = equR.matcher(msg);

        if(equM.matches() && !msg.contains("kW") && !msg.contains("KW")){
            return true;
        }
        return false;
    }
    /****
     * 判断类型是否为MTEXT或者TEXT
     * @param type
     * @return
     */
    private static boolean handleType(String type){
        if("MTEXT".equals(type) || "TEXT".equals(type)){
            return true;
        }
        return false;
    }
    /****
     * 验证是否是三位或者四位数字
     * @param msg
     * @return
     */
    private static Boolean handleNumber(String msg){

        msg = msg.trim();
        //设置正则表达式:三位数字或四位数字
        String equPattern = "^\\d{3,4}$";
        Pattern equR = Pattern.compile(equPattern);
        Matcher equM = equR.matcher(msg);

        return equM.matches();
    }

    /**
     * 正则表达式，验证是否为系统
     * @param msg
     * @return
     */
    private static Boolean handleSystem(String msg){
        //正则表达式，系统规则验证： 三个或4个大写字母
        String pat = "^\\d?[A-Z]{3,4}\\d?$";
        Pattern rtb = Pattern.compile(pat);
        Matcher mtb = rtb.matcher(msg);
        return mtb.matches();
    }

    /**
     * 判断是否为系统
     * @param msg
     * @return
     */
    private static Boolean handleSystemLength(String msg){
        //正则表达式，系统规则验证： 三个或4个大写字母
        String pat = "^\\d?[A-Z]{2,4}\\s*\\d{0,1}$";
        Pattern rtb = Pattern.compile(pat);
        Matcher mtb = rtb.matcher(msg);
        return mtb.matches();
    }

    /**
     * 理索引的子项信息
     * @param msg 处理的字符串
     * @return 布尔值
     */
    private static Boolean handleSubItem(String msg){
        //定义子项的正则表达式:两个大写字母或者两个大写字母加一个数字
        String subPattern = "^\\d?[A-Z]{2}|[A-Z]{2}\\d?$";
        Pattern subR = Pattern.compile(subPattern);
        Matcher subM = subR.matcher(msg);
        return subM.matches();
    }

    /**
     * 处理索引的文件名称
     * @param msg
     * @return
     */
    private static Boolean handleFileName(String msg){
        String companyName = "福建福清核电";
        //定义图纸名称的正则表达式：大于五个汉字，以后可以含有任意字符
        String namePattern =".*[\\u4e00-\\u9fa5]{3,}.*";
        Pattern nameR = Pattern.compile(namePattern);
        Matcher nameM = nameR.matcher(msg);
        if(nameM.matches() && !msg.contains(companyName) && msg.contains("图") && !msg.contains("图中以外") && msg.length()>=5){
            return true;
        }
        return false;
    }

    /****
     * 处理索引版本信息
     * @param msg
     * @return
     */
    private static Boolean handleVersion(String msg){
        //定义版本的验证规则：三位数字
        String vPattern ="^\\d{3}$";
        Pattern vR = Pattern.compile(vPattern);
        Matcher vM = vR.matcher(msg);
        return vM.matches();
    }
    /***
     * 处理索引信息版次
     * @param msg
     * @return
     */
    private static Boolean handleEdition(String msg){
        //定义版次的验证规则：两位数字
        String ePattern ="^\\d{2}$";
        Pattern eR = Pattern.compile(ePattern);
        Matcher eM = eR.matcher(msg);
        return eM.matches();
    }

    /***
     * 判断字符串是三位还是四位数字开始
     * 处理排序时截取字符的位置
     * @param msg
     * @return
     */
    private static boolean getNumLen(String msg){
        String equPattern = "^\\d{3}[a-zA-Z]*\\d?$";
        Pattern equR = Pattern.compile(equPattern);
        Matcher equM = equR.matcher(msg);
        return equM.matches();
    }

    /***
     * 判断是否为9位或者10设备编码
     * @param msg
     * @return
     */
    private static boolean isEquipment(String msg){

        // 过滤掉其中的汉字
        msg = msg.replaceAll("[\\u4e00-\\u9fa5]", "");
        if(msg.contains("(")){
            msg = msg.substring(0, msg.indexOf("("));
        }
        msg = msg.trim();
        //设置正则表达式:两位字母或者以三位字母
        // String equPattern = "^\\d{1}[A-Z]{3}\\d{3,4}[A-Z]{2,3}$";
        String equPattern = "^\\d?[A-Z]{3,4}\\d{3,4}[A-Z]{2,3}$";
        Pattern equR = Pattern.compile(equPattern);
        Matcher equM = equR.matcher(msg);

        return equM.matches();
    }

    /***
     * 处理九位设备编码中的设备码
     * @param msg
     * @return
     */
    private static String subEquipment(String msg){
        msg = msg.trim();
        msg = msg.replaceAll("[\\u4e00-\\u9fa5]", "");
        int index=-1;
        String equPattern = "\\d";
        Pattern equR = Pattern.compile(equPattern);

        if(msg.contains("(")){
            String one = msg.substring(0, msg.indexOf("("));
            String other = msg.substring(msg.indexOf("(")+1, msg.indexOf(")"));
            for(int i=1;i<one.length(); i++){
                if(equR.matcher(msg.charAt(i)+"").matches()){
                    index=i;
                    break;
                }
            }
            String s = one.substring(index);
            if(isEquipment(other)){
                for(int i=1;i<other.length(); i++){
                    if(equR.matcher(msg.charAt(i)+"").matches()){
                        index=i;
                        break;
                    }
                }
                String s2 = other.substring(index);
                if(handleEquipmentCode(s) && handleEquipmentCode(s2)){
                    return s + "-" + s2;
                }
            }else{
                if(handleEquipmentCode(s)){
                    return s;
                }
            }
        } else if(msg.contains("（")){
            String one = msg.substring(0, msg.indexOf("（"));
            String other = msg.substring(msg.indexOf("（")+1, msg.indexOf("）"));
            for(int i=1;i<one.length(); i++){
                if(equR.matcher(msg.charAt(i)+"").matches()){
                    index=i;
                    break;
                }
            }
            String s = one.substring(index);
            if(isEquipment(other)){
                for(int i=1;i<other.length(); i++){
                    if(equR.matcher(msg.charAt(i)+"").matches()){
                        index=i;
                        break;
                    }
                }
                String s2 = other.substring(index);
                if(handleEquipmentCode(s) && handleEquipmentCode(s2)){
                    return s + "-" + s2;
                }
            }else{
                if(handleEquipmentCode(s)){
                    return s;
                }
            }
        }else{
            for(int i=1;i<msg.length(); i++){
                if(equR.matcher(msg.charAt(i)+"").matches()){
                    index=i;
                    break;
                }
            }

            String s = msg.substring(index);
            if(handleEquipmentCode(s)){
                return s;
            }
        }
        return null;
    }
    /****
     * 验证是否是两位或者三位字母
     * @param msg
     * @return
     */
    private static Boolean handleLetter(String msg){
        msg = msg.trim();
        //设置正则表达式:两位字母或者以三位字母
        String equPattern = "^[A-Za-z]{2,3}\\d?$";
        Pattern equR = Pattern.compile(equPattern);
        Matcher equM = equR.matcher(msg);
        return equM.matches();
    }

    /******************************** 通过坐标查找索引信息 ****************************************/
    /****
     * 处理文件名称信息
     *
     * @param fileComponentList
     * @return
     */
    private static String getFileName(List<FileComponent> fileComponentList){

        double x = 0.0;
        double y = 0.0;
        for (FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            if(s.length()<2 ){
                continue;
            }
            if("批准".equals(s)){
                x = fc.getX();
                y = fc.getY();
                break;
            }
        }
        // 判断文件名称位置
        for(FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            // 验证是否符合文件名称的情况
            if(handleFileName(s) || (s.contains("系统") && s.length()>=8)){
                if(fc.getX()>x && fc.getY() < y){
                    return s;
                }
            }
        }
        return null;
    }
    /****
     * 处理版次信息
     * @param fileComponentList
     * @param height
     * @return
     */
    private static String getEdition(List<FileComponent> fileComponentList, double height, double width){

        double x = 0.0;
        double y = 0.0;
        boolean flag = false;
        double propY = 23.0/1000 * height;
        double propX = 10.0/1000 * width;
        for (FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if(s.length()<2 || s.length()>2){
                continue;
            }
            if("版次".equals(s)){
                x = fc.getX();
                y = fc.getY();
                flag = true;
                break;
            }
        }
        if (flag){
            // 验证版次信息
            for (FileComponent fc : fileComponentList){
                String original = fc.getOriginal();
                String s = handleOriginal(original);
                if (s.length()<2){
                    continue;
                }
                // 验证是否符合版次的情况
                if(handleEdition(s)){
                    if((fc.getX()>x && Math.abs(fc.getY() - y) < propY) || (fc.getY() < y && Math.abs(fc.getX() - x) < propX)){
                        return s;
                    }
                }
            }
        }
        return null;
    }

    /***
     * 处理版本信息
     * @param fileComponentList
     * @param height
     * @return
     */
    private static String getVersion(List<FileComponent> fileComponentList, double height, double width){

        double x = 0.0;
        double y = 0.0;
        double propY = 23.0/1000 * height;
        double propX = 10.0/1000 * width;
        for (FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            if("版本".equals(s)){
                x = fc.getX();
                y = fc.getY();
                break;
            }
        }
        // 解析版本数据
        for(FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            // 验证是否符合版本的情况
            if(handleVersion(s)){
                if((fc.getX()>x && Math.abs(fc.getY() - y) < propY) || (fc.getY() < y && Math.abs(fc.getX() - x) < propX)){
                    return s;
                }
            }
        }
        return null;
    }

    /***
     * 处理系统信息
     * @param fileComponentList
     * @param height
     * @return
     */
    private static String getSystem(List<FileComponent> fileComponentList, double height, double width){

        double x = 0.0;
        double y = 0.0;
        double propY = 23.0/1000 * height;
        double propX = 10.0/1000 * width;
        for (FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            if("系统".equals(s)){
                x = fc.getX();
                y = fc.getY();
                break;
            }
        }
        // 查找系统
        for(FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            // 验证是否符合版本的情况
            if(handleSystemLength(s)){
                if((fc.getX()>x && Math.abs(fc.getY() - y) < propY) || (fc.getY() < y && Math.abs(fc.getX() - x) < propX)){
                    return s;
                }
            }
        }
        return null;
    }

    /***
     * 处理子项信息
     * @param fileComponentList
     * @param height
     * @return
     */
    private static String getSubItem(List<FileComponent> fileComponentList, double height, double width){

        double sx = 0.0;
        double sy = 0.0;
        double vx = 0.0;
        double vy = 0.0;
        double propY = 23.0/1000 * height;
        if(height < 800){
            propY = 9.0/1000 * height;
        }
        double propX = 10.0/1000 * width;
        for (FileComponent fc : fileComponentList){
            String original = fc.getOriginal();
            String s = handleOriginal(original);
            if (s.length()<2){
                continue;
            }
            if("子项".equals(s)){
                sx = fc.getX();
                sy = fc.getY();
            }
            if("系统".equals(s)){
                vx = fc.getX();
                vy = fc.getY();
            }

        }

        if(width>height){
            // 获取子项
            for(FileComponent fc:fileComponentList){
                String s = handleOriginal(fc.getOriginal());
                if (s.length()<2){
                    continue;
                }
                if(handleSubItem(s)){
                    if(fc.getX()>sx && Math.abs(fc.getY() - sy) < propY){
                        return s;
                    }
                }
                // 验证是否符合子项的情况
                if(fc.getX()>sx && Math.abs(fc.getY() - sy) < propY){
                    if(fc.getX() < vx){
                        return s;
                    }
                }
            }
        }else{
            for(FileComponent fc:fileComponentList){
                String s = handleOriginal(fc.getOriginal());

                if (s.length()<2){
                    continue;
                }
                if(handleSubItem(s)){
                    if(fc.getY() < sy && Math.abs(fc.getX() - sx) < propX){
                        return s;
                    }
                }
                // 验证是否符合子项的情况
                if(fc.getX()>sx && Math.abs(fc.getY() - sy) < propY){
                    if(fc.getX() < vx){
                        return s;
                    }
                }

                if(fc.getY() < sy && Math.abs(fc.getX() - sx) < propX){
                    if(fc.getY() > vy){
                        return s;
                    }
                }
            }
        }
        return null;
    }
}
